<?php
namespace Kuoqi\FileDriver;
class UploadSec{

    //判定是否有文件信息，如果有文件走文件的流程
    protected $has_file = false;

    protected $file = null;//文件信息
    protected $fileReader = null;//阅读的文件指针信息
    protected $buffer = null;//文件buffer信息
    protected $is_valied = true;//是否验证信息
    protected $errmsg = '';//异常的内容信息
    protected $path = '';//缓存的路径信息
    public $upload_path = '';//上传链接地址信息
    protected $info = array();

    public $tmp = array();//文件资源信息们
    public $args = array();//当前请求的参数信息，这个要求比较多

    public function __construct()
    {
        //兼容当前文件，这个是单个文件上传的模块
        $this->file = reset($_FILES);
        if($this->file){
            $this->has_file = true;
        }else{
            $this->has_file = false;
        }

        $this->args = $_REQUEST;
        $this->is_valied = true;
        //执行上传文件的部分
        $this->fileReader = new \Kuoqi\FileDriver();
        $this->path = '/'.\Kuoqi\Config::get('RUNTIME_PATH').'/tmp_upload';
        $this->upload_path = '/assets/upload';//文件上传的位置
    }

    /**
     * 判定是否有上传文件信息
     * @return bool
     */
    public function hasFile(){
        return $this->has_file;
    }

    /**
     * 是否还有下一个片段
     * @return bool
     */
    public function hasNext(){
        if($this->args['sec_index'] + 1>=$this->args['sec_count']){
            return false;
        }else{
            return true;
        }
    }

    /**
     * 文件上传的部分
     * @return bool
     */
    public function upload(){
        //核验切片数据信息
        if(!$this->validInfo()){ return $this->is_valied;}
        if(!$this->validFile()){ return $this->is_valied;}
        //获取量级长度
        $len = ceil(strlen($this->args['sec_count']))+1;
        $fnx = str_pad($this->args['sec_index'],$len,0,STR_PAD_LEFT);
        $fn = $this->args['file_md5'].'_'.$this->args['sec_count'].'_'.$fnx;
        $this->fileReader->setBasename($fn);
        $this->fileReader->setDirname($this->path);
        $this->fileReader->setContent(file_get_contents($this->file['tmp_name']));
        if($this->fileReader->getMd5()!=$this->args['sec_md5']){
            $this->is_valied = false;
            $this->errmsg = '文件已失真，上传失败';
            return false;
        }
        //判定md5是否匹配
        if($this->fileReader->save(true)){
            //移动文件完成之后，返回true
            return true;
        }else{
            $this->is_valied = false;
            $this->errmsg = '移动上传文件失败';
            return false;
        }
    }

    //对文件进行最后的组装
    public function flushComplete(){
        //获取所有文件列表
        $list = $this->fileReader->getList();
        sort($list);
        //然后获取这所有的文件列表，并重新组合信息们
        //组合最后的文件
        $ext = strrchr($this->file['name'],'.');
        if(!Mime::ext2mime($ext)){
            $ext = Mime::mime2ext($this->file['type']);
        }
        if(!$ext){
            $this->errmsg = '无法保存['.$this->file['type'].']文件类型，程序禁止';
            $this->is_valied = 0;
            return false;
        }
        $upflie = $this->upload_path.'/'.substr($ext,1).'/'.date('Ymd').'/'
            .md5($this->args['file_md5'].time()).$ext;
        $upflie = new \Kuoqi\FileDriver($upflie);
        if(!$upflie->checkPath()){
            $this->errmsg = '暂无权限-'.$upflie->getError();
            $this->is_valied = 0;
            return false;
        }

        $isbase64 = false;
        if(isset($this->args['format'])&&$this->args['format']=='base64encode'){
            $isbase64 = true;
        }
        $handle = @fopen($upflie->getFullfile(),'a+');
        if(!$handle){
            $this->errmsg = '文件打开失败-'.$upflie->getFile();
            $this->is_valied = 0;
            return false;
        }
        //$tmppath = $this->fileReader->getFullpath();
        foreach($list as $v){
            if(in_array($v,array('.','..'))){ continue;}
            $this->fileReader->setBasename($v);
            if($isbase64){
                fwrite($handle,base64_decode($this->fileReader->getContent(false)));
            }else{
                fwrite($handle,$this->fileReader->getContent(false));
            }
            //写入之后删除本文件
            $this->fileReader->delete();
        }
        $upflie->fclose();
        $this->buffer = $upflie;
        $this->info['mime'] = $this->file['type'];
        $this->info['ext'] = $ext;
        $this->info['name'] = $this->file['name'];
        $this->info['filename'] = $this->buffer->getFilename();
        $this->info['url'] = $this->buffer->getUrl();
        $this->info['size'] = $this->file['size'];
        $this->info['md5'] = $this->buffer->getMd5();
        return true;
    }

    //核验上传文件是否符合规范
    public function validFile(){
        //判定文件是否完整
        if(!$this->file){
            $this->errmsg = '上传文件为空';
            $this->is_valied = false;
        }
        switch($this->file['error']){
            case 1:
                $this->errmsg = '上传的文件超过了服务器选项限制的值。';
                $this->is_valied = false;
                break;
            case 2:
                $this->errmsg = '上传文件的大小超过了 HTML 表单中 MAX_FILE_SIZE 选项指定的值。';
                $this->is_valied = false;
                break;
            case 3:
                $this->errmsg = '文件只有部分被上传。';
                $this->is_valied = false;
                break;
            case 4:
                $this->errmsg = '没有文件被上传';
                $this->is_valied = false;
                break;
            case 6:
                $this->errmsg = '找不到临时文件夹。PHP 4.3.10 和 PHP 5.0.3 引进。';
                $this->is_valied = false;
                break;
            case 7:
                $this->errmsg = '文件写入失败。PHP 5.1.0 引进';
                $this->is_valied = false;
                break;
            default:;
        }
        return $this->is_valied;
    }

    /**
     * 核验文件切片信息
     */
    private function validInfo(){
        if(isset($this->args['file_md5'])){

        }else{
            $this->is_valied = false;
            $this->errmsg = '参数[file_md5]为必传';
        }
        if(isset($this->args['sec_md5'])){

        }else{
            $this->is_valied = false;
            $this->errmsg = '参数[sec_md5]为必传';
        }
        if(isset($this->args['sec_index'])){

        }else{
            $this->is_valied = false;
            $this->errmsg = '需要上传参数的当前片段ID,参数[sec_index]为必传';
        }
        if(isset($this->args['sec_count'])){

        }else{
            $this->is_valied = false;
            $this->errmsg = '需要上传参数的所有片段数量，参数[sec_count]为必传';
        }
        return $this->is_valied;
    }

    /**
     * 获取基础信息
     * @return array
     */
    public function info()
    {
        return $this->info;
    }

    /**
     * 获取异常信息
     * @return string
     */
    public function getError(){
        return $this->errmsg;
    }

    /**
     * 获取文件信息
     * @return null
     */
    public function getFile(){
        return $this->buffer;
    }

    //初始化的参数配置信息
    public function infoConfig(){
        return array(

        );
    }

}